﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

namespace TVLDesktop
{

    public partial class IniciativaL5A : Form
    {
        public IniciativaL5A()
        {
            InitializeComponent();
        }

        private void btnTirar_Click(object sender, EventArgs e)
        {
            tsProceso.Text = "Calculando iniciativas...";
            Iniciativas aux = new Iniciativas();
            Iniciativas aux2 = new Iniciativas();
            List<Iniciativas> todos = new List<Iniciativas>();
            tsProgreso.Maximum = tabla.Rows.Count-1;
            System.Threading.Thread.Sleep(2);
            for (int i = 0; i < tabla.Rows.Count - 1; i++)
            {
                aux = new Iniciativas();
                if (tabla.Rows[i].Cells[0].Value != null)
                    aux.Nombre = tabla.Rows[i].Cells[0].Value.ToString();
                else
                    aux.Nombre = "Nombre";

                if (tabla.Rows[i].Cells[1].Value != null)
                    aux.DadosTirar = int.Parse(tabla.Rows[i].Cells[1].Value.ToString());
                else
                    aux.DadosTirar = 1;
                if (tabla.Rows[i].Cells[2].Value != null)
                    aux.DadosGuardar = int.Parse(tabla.Rows[i].Cells[2].Value.ToString());
                else
                    aux.DadosGuardar = 1;

                if (tabla.Rows[i].Cells[3].Value != null)
                    aux.Reflejos = int.Parse(tabla.Rows[i].Cells[3].Value.ToString());
                else
                    aux.Reflejos = 2;

                if (tabla.Rows[i].Cells[4].Value != null)
                    aux.ReflejosCombate = bool.Parse(tabla.Rows[i].Cells[4].Value.ToString());
                else
                    aux.ReflejosCombate = false;
                aux.CalcularIniciativa();
                todos.Add(aux);
                tsProgreso.Value++;
            }

            tabla.Rows.Clear();
            Iniciativas[] arr= new Iniciativas[todos.Count];
            arr = todos.ToArray();
            Array.Sort(arr, Iniciativas.TiradaDESC());
            todos = arr.ToList();
            for (int i = 1; i < todos.Count; i++)
            {
                if (todos[i].ReflejosCombate)
                {
                    aux = todos[i-1];
                    todos[i - 1] = todos[i];
                    todos[i] = aux;
                }
            }
            for (int j = 0; j < todos.Count; j++)
            {
                tabla.Rows.Add();
                tabla.Rows[j].Cells[0].Value = todos[j].Nombre;
                tabla.Rows[j].Cells[1].Value = todos[j].DadosTirar;
                tabla.Rows[j].Cells[2].Value = todos[j].DadosGuardar;
                tabla.Rows[j].Cells[3].Value = todos[j].Reflejos;
                tabla.Rows[j].Cells[4].Value = todos[j].ReflejosCombate;
                tabla.Rows[j].Cells[5].Value = todos[j].UltimaTirada;

            }
            arr = null;
            todos = null;
            MessageBox.Show("Tiradas generadas correctamente", "Bienn!", MessageBoxButtons.OK);
            tsProgreso.Value = 0;
            tsProceso.Text = "Standby";
        }

        private void guardarToolStripMenuItem_Click(object sender, EventArgs e)
        {
            saveFileDialog1.ShowDialog(this);
        }

        private void saveFileDialog1_FileOk(object sender, CancelEventArgs e)
        {
            Iniciativas aux = new Iniciativas();
            tsProceso.Text = "Guardando datos";
            tsProgreso.Maximum = tabla.Rows.Count-1;
            List<Iniciativas> todos = new List<Iniciativas>();
            for (int i = 0; i < tabla.Rows.Count - 1; i++)
            {
                aux = new Iniciativas();
                if (tabla.Rows[i].Cells[0].Value != null)
                    aux.Nombre = tabla.Rows[i].Cells[0].Value.ToString();
                else
                    aux.Nombre = "Nombre";

                if (tabla.Rows[i].Cells[1].Value != null)
                    aux.DadosTirar = int.Parse(tabla.Rows[i].Cells[1].Value.ToString());
                else
                    aux.DadosTirar = 1;
                if (tabla.Rows[i].Cells[2].Value != null)
                    aux.DadosGuardar = int.Parse(tabla.Rows[i].Cells[2].Value.ToString());
                else
                    aux.DadosGuardar = 1;

                if (tabla.Rows[i].Cells[3].Value != null)
                    aux.Reflejos = int.Parse(tabla.Rows[i].Cells[3].Value.ToString());
                else
                    aux.Reflejos = 2;

                if (tabla.Rows[i].Cells[4].Value != null)
                    aux.ReflejosCombate = bool.Parse(tabla.Rows[i].Cells[4].Value.ToString());
                else
                    aux.ReflejosCombate = false;
                if (tabla.Rows[i].Cells[5].Value != null)
                    aux.ReflejosCombate = bool.Parse(tabla.Rows[i].Cells[4].Value.ToString());
                else
                    aux.UltimaTirada = 0;
                todos.Add(aux);
            }
            FileStream fs = new FileStream(saveFileDialog1.FileName, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None);
            /*BinaryFormatter BF = new BinaryFormatter();
            BF.Serialize(fs, todos);*/
            BinaryWriter BW = new BinaryWriter(fs, Encoding.UTF8);
            BW.Write(todos.Count);
            for (int z = 0; z < todos.Count; z++)
            {
                BW.Write(todos[z].Nombre);
                BW.Write(todos[z].DadosTirar);
                BW.Write(todos[z].DadosGuardar);
                BW.Write(todos[z].Reflejos);
                BW.Write(todos[z].ReflejosCombate);
                BW.Write(todos[z].UltimaTirada);
                tsProgreso.Value++;
            }
            fs.Flush();
            fs.Close();
            MessageBox.Show("Datos guardados correctamente", "Bienn!", MessageBoxButtons.OK);
            tsProgreso.Value = 0;
            tsProceso.Text = "Standby";

        }

        private void cargarToolStripMenuItem_Click(object sender, EventArgs e)
        {
            openFileDialog1.ShowDialog(this);
        }

        private void openFileDialog1_FileOk(object sender, CancelEventArgs e)
        {
            int actual = tabla.Rows.Count - 1;
            tsProceso.Text = "Cargando datos...";
            DialogResult asd = MessageBox.Show("¿Quieres borrar lo que hay actualmente en la tabla?", "Ey!!!",MessageBoxButtons.YesNo);
            if (asd == DialogResult.Yes)
            {
                tabla.Rows.Clear();
                actual = 0;
            }
            FileStream fs = new FileStream(openFileDialog1.FileName,FileMode.Open, FileAccess.Read);
            BinaryReader BR = new BinaryReader(fs, Encoding.UTF8);
            int cant = BR.ReadInt32();
            tsProgreso.Maximum = cant;
            for (int i = 0; i < cant; i++)
            {
                tabla.Rows.Add();
                tabla.Rows[i + actual].Cells[0].Value = BR.ReadString();
                tabla.Rows[i + actual].Cells[1].Value = BR.ReadInt32();//dados tirar
                tabla.Rows[i + actual].Cells[2].Value = BR.ReadInt32();//dados guardar
                tabla.Rows[i + actual].Cells[3].Value = BR.ReadInt32();//reflejos
                tabla.Rows[i + actual].Cells[4].Value = BR.ReadBoolean();//ReflejosCombate
                tabla.Rows[i + actual].Cells[5].Value = BR.ReadInt32();//Tirada
                tsProgreso.Value++;
            }
            fs.Flush();
            fs.Close();
            MessageBox.Show("Datos importados correctamente", "Bienn!!", MessageBoxButtons.OK);
            tsProgreso.Value = 0;
            tsProceso.Text = "Standby";
        }

        private void IniciativaL5A_Load(object sender, EventArgs e)
        {

        }

        private void tabla_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {

        }

    }

    class Iniciativas : IComparable
    {
        public string Nombre;
        public int DadosGuardar;
        public int DadosTirar;
        public int UltimaTirada;
        public int Reflejos;
        public bool ReflejosCombate;

        public int CalcularIniciativa()
        {
            Random rand = new Random(DateTime.Now.Millisecond.GetHashCode());
            List<int> cantidadTirar = new List<int>();
            int acum = 0;
            int total = 0;
            int num = 0;
            for (int i = 1; i <= DadosTirar; i++)//Tirar todos los dados
            {
                
                acum = 0;
                do
                {
                    
                    num = rand.Next(1, 11);
                    acum += num; 
                    System.Threading.Thread.Sleep(2);
                    if (num == 11)
                        MessageBox.Show("¡UN 11!");
                } while (num == 10);
                cantidadTirar.Add(acum);
                total += acum;
            }
            int deshechar = DadosTirar - DadosGuardar;
            for (int j = 0; j < deshechar; j++)
            {
                total -= cantidadTirar.Min();
                cantidadTirar.Remove(cantidadTirar.Min());
            }
            total += Reflejos;
            UltimaTirada = total;
            return total;
        }

        private class OrdenarUltimaTiradaAscendenteHelper : IComparer
        {
            int IComparer.Compare(object a, object b)
            {
                Iniciativas c1 = (Iniciativas)a;
                Iniciativas c2 = (Iniciativas)b;

                if (c1.UltimaTirada > c2.UltimaTirada)
                    return 1;
                else if (c1.UltimaTirada < c2.UltimaTirada)
                    return -1;/*
                else if(c1.UltimaTirada==c2.UltimaTirada)
                {
                    if (c1.Reflejos > c2.Reflejos)
                        return 1;
                    else
                        return -1;
                }*/
                else
                    return 0;
            }
        }

        // Nested class to do descending sort on year property.
        private class OrdenarUltimaTiradaDescendenteHelper : IComparer
        {
            int IComparer.Compare(object a, object b)
            {
                Iniciativas c1 = (Iniciativas)a;
                Iniciativas c2 = (Iniciativas)b;

                if (c1.UltimaTirada < c2.UltimaTirada)
                    return 1;
                else if (c1.UltimaTirada > c2.UltimaTirada)
                    return -1;/*
                else if(c1.UltimaTirada==c2.UltimaTirada)
                {
                    if (c1.Reflejos < c2.Reflejos)
                        return 1;
                    else
                        return -1;
                }*/
                else
                    return 0;
            }
        }

        private class OrdenarNombreDescendenteHelper : IComparer
        {
            int IComparer.Compare(object a, object b)
            {
                Iniciativas c1 = (Iniciativas)a;
                Iniciativas c2 = (Iniciativas)b;
                return String.Compare(c2.Nombre, c1.Nombre);
            }
        }

        int IComparable.CompareTo(object obj)
        {
            Iniciativas c = (Iniciativas)obj;
            return String.Compare(this.Nombre, c.Nombre);
        }

        // Method to return IComparer object for sort helper.
        public static IComparer TiradaASC()
        {
            return (IComparer)new OrdenarUltimaTiradaAscendenteHelper();
        }

        // Method to return IComparer object for sort helper.
        public static IComparer TiradaDESC()
        {
            return (IComparer)new OrdenarUltimaTiradaDescendenteHelper();
        }

        // Method to return IComparer object for sort helper.
        public static IComparer NombreDESC()
        {
            return (IComparer)new OrdenarNombreDescendenteHelper();
        }

    }
}
